﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using Rhino.Mocks;

namespace ValidateAndVerify
{
    [TestFixture]
    public class Stubs
    {
        [Test]
        public void Demonstrate_Stub_Implements_the_passed_type()
        {
            // Arrange

            // Act 
            var stub = MockRepository.GenerateStub<IFoo>();

            // Assert
            Assert.That(stub, Is.InstanceOf<IFoo>());
        }

        /// <summary>
        /// When you need to mock a read-only property of a class.
        /// </summary>
        [Test]
        public void How_to_Stub_out_your_own_value_of_a_ReadOnlyProperty()
        {
            // Arrange
            var foo = MockRepository.GenerateStub<IFoo>();
            foo.Stub(x => x.ID).Return(123);

            // Act
            var id = foo.ID;

            // Assert
            Assert.That(id, Is.EqualTo(123));
        }

        [Test]
        public void When_user_forgot_password_should_save_user()
        {
            var stubUserRepository = MockRepository.GenerateStub<IFoo>();

            var theUser = new Foo("zsolti");

            stubUserRepository.Stub(x => x.getName()).Return("zsolti");

            var controllerUnderTest = new FooController(stubUserRepository);

            controllerUnderTest.DoSomething("zsolti");

            stubUserRepository.AssertWasCalled(x => x.doSomethingFoo("zsolti"));
        }

        /// <summary>
        /// This is just a sample interface, what it is or does isn't really relevant. It could
        /// be IUser of IOrder
        /// </summary>
        public interface IFoo
        {
            int ID { get; }
            string Name { get; set; }
            String getName();
            void doSomethingFoo(String name);
        }

        public class Foo : IFoo
        {
            private int id;
            public static int idCounter = 0;

            public int ID
            {
                get { return id; }
            }

            public string Name { get; set; }

            public string getName() { return Name; }

            public Foo() {}
            public Foo(String name) {
                this.id = idCounter++;
                this.Name = name;
            }

            public void doSomethingFoo(String name)
            {

            }
        }

        public interface IOtherFoo
        {
            int ID { get; }
            string Name { get; set; }
        }

        public class OtherFoo : IOtherFoo
        {
            public int ID
            {
                get { return ID; }
            }
            public string Name { get; set; }
        }

        public class FooController{
            IFoo iFoo;
            public FooController() { }
            public FooController(IFoo iFoo){
                this.iFoo = iFoo;

            }

            public void DoSomething(String name){
                iFoo.doSomethingFoo("zsolti");
            }
        }
    }
}
